/**
 * 漆水河 脚手架基础公开课
 * 2022/8/13 --- 2022/12/13
 * 有疑问可加QQ群: 809126489，后续会持续输出与大家一起成长
 */
package com.qishuihe.common.infrastructure.security.config;


import com.qishuihe.baseinterface.constant.CommonConstant;
import com.qishuihe.common.infrastructure.security.filter.JWTSecurityFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.access.AccessDeniedHandler;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import springfox.documentation.builders.*;
import springfox.documentation.oas.annotations.EnableOpenApi;
import springfox.documentation.schema.ScalarType;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ParameterType;
import springfox.documentation.service.RequestParameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;

import java.util.ArrayList;
import java.util.List;

/**
 * @author Joe Grandja
 * @since 0.0.1
 */

@Configuration
@EnableGlobalMethodSecurity(prePostEnabled = true)
@EnableOpenApi
public class AuthorizationServerConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private JWTSecurityFilter jwtSecurityFilter;

    @Autowired
    private AccessDeniedHandler accessDeniedHandlerImpl;

    @Autowired
    private AuthenticationEntryPoint authenticationEntryPointImpl;
    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        super.configure(http);
        http.csrf().disable()
                .sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and().authorizeRequests()
                .regexMatchers("//com.qishuihe.designapp/*","//com.qishuihe.runningapp/*").anonymous()
                .antMatchers("//com.qishuihe.designapp/*","//com.qishuihe.runningapp/*","//com.qishuihe.runningapp/*","/swagger-ui/*","/swagger**","/v2/api-docs","/webjars/**","/swagger-resources/**","/favicon.ico","/admin/login","/admin/sendResetLink","/admin/sendVerifyCode").anonymous()
                .anyRequest().authenticated().and().addFilterBefore(jwtSecurityFilter, UsernamePasswordAuthenticationFilter.class)
                .exceptionHandling().authenticationEntryPoint(authenticationEntryPointImpl)
                .accessDeniedHandler(accessDeniedHandlerImpl);
    }
    @Bean
    public AuthenticationManager authenticationManagerBean() throws Exception {
        return super.authenticationManagerBean();
    }
    @Bean
    public PasswordEncoder getPasswordEncoder(){
        return  new BCryptPasswordEncoder();
    }
    @Bean
    public Docket webApiConfig(){
        return new Docket(DocumentationType.SWAGGER_2).groupName("webApi").apiInfo(webApiInfo()).select().paths(PathSelectors.regex("/error").negate()).build().globalRequestParameters(getParameterList());
    }

    private ApiInfo webApiInfo(){
        return new ApiInfoBuilder().title("漆水河API中心").description("spring boot 从零开始").version("1.0").build();
    }

    private List<RequestParameter> getParameterList(){
        List<RequestParameter> parameters = new ArrayList<>();
        parameters.add(new RequestParameterBuilder()
                .name(CommonConstant.TOKEN_STR)
                .description("请求令牌")
                .in(ParameterType.HEADER)
                .query(q -> q.model(m -> m.scalarModel(ScalarType.STRING)))
                .required(false)
                .build());
        return parameters;
    }

}
